﻿/**************************************************************************************
 * KillPlugin
 * Deletes a plugin from the Dynamics CRM database
 *
 * @copyright    Copyright (c) 2013, CRM Accelerators (http://www.crmaccelerators.net)
 * @license      Microsoft Public License (Ms-PL)
 * @developer    Mitch Milam (http://blogs.infinite-x.net)
 * @version      1.0
 *
 * THIS SOFTWARE IS PROVIDED BY CRM Accelerators ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL CRM Accelerators BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************************/

using System;
using System.IO;
using System.Net;
using System.ServiceModel;
using System.Text;
using Microsoft.Xrm.Sdk;

namespace KillPlugin
{
    public static class Utility
    {
        public static void WriteToFile(string fileName, string message)
        {
            using (var writer = new StreamWriter(fileName))
            {
                writer.Write(message);
            }
        }

        public static void WriteToFile(string fileName, StringBuilder sb)
        {
            using (var writer = new StreamWriter(fileName))
            {
                writer.Write(sb.ToString());
            }
        }

        public static void UpdateStatus(string message, bool newline)
        {
            if (newline)
            {
                Console.WriteLine(message);
            }
            else
            {
                Console.Write(message);
            }
        }

        public static void ShowError(string message)
        {
            Console.WriteLine("ERROR: {0}", message);
        }

        public static void ShowError(StringBuilder sb)
        {
            Console.WriteLine("ERROR: {0}", sb);
        }

        public static string BuildConnectionString(string userName, string password, string domain, string crmServerUrl)
        {
            if (string.IsNullOrEmpty(userName) &&
                string.IsNullOrEmpty(password) &&
                string.IsNullOrEmpty(domain))
            {
                return string.Format("Url={0};", crmServerUrl);
            }

            return string.Format("Url={0}; Domain={1}; Username={2}; Password={3}", crmServerUrl, domain, userName, password);
        }

        public static string HandleExceptions(Exception ex)
        {
            var sb = new StringBuilder();

            if (ex is WebException)
            {
                sb.Append(ex.Message);
            }
            else if (ex is FaultException<DiscoveryServiceFault>)
            {
                var faultException = ex.InnerException as FaultException<DiscoveryServiceFault>;

                if (faultException != null)
                {
                    sb.AppendFormat("Timestamp:\t{0}{1}", faultException.Detail.Timestamp, Environment.NewLine);
                    sb.AppendFormat("Code:\t{0}{1}", faultException.Detail.ErrorCode, Environment.NewLine);
                    sb.AppendFormat("Message:\t{0}{1}", faultException.Detail.Message, Environment.NewLine);
                    sb.AppendFormat("Inner Fault:\t{0}{1}",
                                    null == faultException.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault",
                                    Environment.NewLine);
                }
            }
            else if (ex is FaultException<OrganizationServiceFault>)
            {
                sb.AppendFormat("{0}{1}", ex.Message, Environment.NewLine);

                if (ex.InnerException != null)
                {
                    sb.AppendFormat("{0}{1}", ex.InnerException.Message, Environment.NewLine);

                    var innerFaultException = ex.InnerException as FaultException<OrganizationServiceFault>;

                    if (innerFaultException != null)
                    {
                        sb.AppendFormat("Timestamp:\t{0}{1}", innerFaultException.Detail.Timestamp, Environment.NewLine);
                        sb.AppendFormat("Code:\t{0}{1}", innerFaultException.Detail.ErrorCode, Environment.NewLine);
                        sb.AppendFormat("Message:\t{0}{1}", innerFaultException.Detail.Message, Environment.NewLine);
                        sb.AppendFormat("Trace:\t{0}{1}", innerFaultException.Detail.TraceText, Environment.NewLine);
                        sb.AppendFormat("Inner Fault:\t{0}{1}",
                                        null == innerFaultException.Detail.InnerFault
                                            ? "Has Inner Fault"
                                            : "No Inner Fault", Environment.NewLine);
                    }
                }
            }
            else if (ex is TimeoutException)
            {
                sb.AppendFormat("Message:\t{0}{1}", ex.Message, Environment.NewLine);
                sb.AppendFormat("Stack Trace:\t{0}{1}", ex.StackTrace, Environment.NewLine);
                sb.AppendFormat("Inner Fault:\t{0}{1}", "No Inner Fault", Environment.NewLine);
            }
            else
            {
                sb.AppendFormat("{0}{1}", ex.Message, Environment.NewLine);

                if (ex.InnerException != null)
                {
                    sb.AppendFormat("{0}{1}", ex.InnerException.Message, Environment.NewLine);

                    var innerFaultException = ex.InnerException as FaultException<OrganizationServiceFault>;

                    if (innerFaultException != null)
                    {
                        sb.AppendFormat("Timestamp:\t{0}{1}", innerFaultException.Detail.Timestamp, Environment.NewLine);
                        sb.AppendFormat("Code:\t{0}{1}", innerFaultException.Detail.ErrorCode, Environment.NewLine);
                        sb.AppendFormat("Message:\t{0}{1}", innerFaultException.Detail.Message, Environment.NewLine);
                        sb.AppendFormat("Trace:\t{0}{1}", innerFaultException.Detail.TraceText, Environment.NewLine);
                        sb.AppendFormat("Inner Fault:\t{0}{1}",
                                        null == innerFaultException.Detail.InnerFault
                                            ? "Has Inner Fault"
                                            : "No Inner Fault", Environment.NewLine);
                    }
                }
            }

            // EventLog.WriteEntry(Resources.PRODUCT_NAME, String.Format("{0}", sb), EventLogEntryType.Error, 100);

            return sb.ToString();
        }
    }
}
